package com.cskaoyan.shiro;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;

@Configuration
public class ShiroConfiguration {

    /**
     * Shiro的Filter
     * 在SpringBoot应用中Filter只需要注册到容器中就会生效 → 可以引用容器中的其他组件
     * ShiroFilterFactoryBean implements FactoryBean
     *
     * authc → isAuthenticated 为true才能通过 → 这个值怎么才能变为true → 需要登录 需要写登录请求
     * perms → hasPermission 为true才能通过
     *
     *
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        // Map 的key： 请求的URI
        // Map 的value： 过滤器的名称
        // 过滤器是有序的 → 提供的Map里的键值对也是有序的 → LinkedHashMap
        // URI的书写，可以使用通配符 (1) * (2)**
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/wx/home/index", "anon");
        filterChainDefinitionMap.put("/wx/goods/*", "anon");
        filterChainDefinitionMap.put("/wx/auth/*", "anon");
        filterChainDefinitionMap.put("/wx/cart/*", "authc");
        filterChainDefinitionMap.put("/wx/order/list", "perms[orderlist]");

        // 如果没有登录的话，它会重定向 /login.jsp → 要修改重定向的地址
        filterFactoryBean.setLoginUrl("/wx/auth/unAuthc"); // 通过开发handler响应一段JSON字符串


        filterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);


        filterFactoryBean.setSecurityManager(securityManager);
        return filterFactoryBean;
    }

    // Realm是容器中的组件
    // SecurityManager是容器中的组件
    // ShiroFilter也是容器中的组件
    @Bean
    public DefaultWebSecurityManager securityManager(CustomRealm customRealm,DefaultWebSessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置认证器，但是你可以不设置，它会给你提供一个默认的认证器(ModularRealmAuthenticator)
        // securityManager.setAuthenticator();

        // 设置认证器，但是你可以不设置，它会给你提供一个默认的授权器(ModularRealmAuthorizer)
        //securityManager.setAuthorizer();

        // 给默认的认证器和授权器 提供realm
        securityManager.setRealm(customRealm);
        securityManager.setSessionManager(sessionManager);

        return securityManager;
    }

    // 访问需要认证才能够访问的请求的时候，发现访问不到 → 放行之后发现Session和Subject变了
    // 想要拿到原先的Subject，要保证使用同一个Session
    // Shiro提供了SessionManager → 用来管理Session
    //  SessionManager 要保证使用的同一个Session，那么他们的id要相同
    @Bean
    public DefaultWebSessionManager sessionManager() {
        return new CustomSessionManager();
    }


}
